var Tree = function () {
    var self = this;
    this.setting = {};
    var treeSearchKey = null;
    var nodeList = [], fontCss = {};
    var curDragNodes, autoExpandNode;
    var treeId = null,
        treeUrl = ROOT_PATH +"upms/resource/move";

    function onAsyncError(event, treeId, treeNode, XMLHttpRequest, textStatus, errorThrown) {
        Dialog.danger("数据加载失败，请联系管理员!");
    }

    /**
     * 异步加载数据成功时触发。
     */
    var onAsyncSuccess = function (event, treeId, treeNode, msg) {
        var zTree = $.fn.zTree.getZTreeObj(treeId);
        // 给根节点添加图标
        var root = zTree.getNodeByParam("level", 0, null);
        //if (root) {
        //    root.iconSkin = "pIcon01";
        //}
        zTree.updateNode(root);
        zTree.expandNode(root, true, null, null, null);
        // 收拢
        $("#foldBtn").bind("click", function () {
            var zTree = $.fn.zTree.getZTreeObj(treeId);
            var nodes = zTree.getNodesByParam("level", "1", null);
            $(nodes).each(function (i) {
                zTree.expandNode(nodes[i], false, null, null, null);
            });
        });
        // 展开
        $("#expandBtn").bind("click", function () {
            var zTree = $.fn.zTree.getZTreeObj(treeId);
            zTree.expandAll(true);
        });

        $("#searchBtn").bind("click", searchNode);
        treeSearchKey = $("#key");
        treeSearchKey.val("");
        treeSearchKey.bind("focus", focusKey).bind("blur", blurKey);

        // 执行加载完成后,只读树的扩展事件，比如默认选中。
        if ($.isFunction(readOnlySetting.callback.extendsAsyncSuccess)) {
            readOnlySetting.callback.extendsAsyncSuccess(zTree);
        }
    }

    // 简单树的初始化参数
    var readOnlySetting = {
        async: {
            enable: true,
            contentType: "application/json",
            dataType: "json",
            autoParam: ["id", "name=n", "level=lv"],
            dataFilter: filter
        },
        view: {
            expandSpeed: "normal",
            showLine: false,
            selectedMulti: true,
            dblClickExpand: true,
            nameIsHTML: true,
            fontCss: getFontCss
        },
        check: {
            enable: true,
            chkStyle: "checkbox",
            chkDisabledInherit: true,
            chkboxType: {
                "Y": "s",
                "N": "s"
            }
        },

        data: {
            key: {
                url: "" // 不让url跳转
            },
            simpleData: {
                enable: true,
                idKey: "id",
                pIdKey: "pid",
                rootPId: null
            }
        },
        callback: {
            // beforeClick : beforeClick,
            onAsyncError: onAsyncError,
            onAsyncSuccess: onAsyncSuccess
        }
    };


    var adminTreeSetting = {
        async: {
            enable: true,
            contentType: "application/json",
            dataType: "json",
            autoParam: ["id", "name=n", "level=lv"],
            otherParam: {
                "otherParam": "zTreeAsyncTest"
            },
            dataFilter: filter
        },
        view: {
            addHoverDom: addHoverDom,// 用于当鼠标移动到节点上时，显示用户自定义控件
            removeHoverDom: removeHoverDom, // 用于当鼠标移动到节点上时，隐藏用户自定义控件
            selectedMulti: false,// 设置是否允许同时选中多个节点
            nameIsHTML: true,
            // 个性化文字样式
            fontCss: getFontCss
        },
        edit: {
            drag: {
                // 拖拽时父节点自动展开是否触发 onExpand
                autoExpandTrigger: true,
                prev: dropPrev,
                inner: dropInner,
                next: dropNext
            },
            // 设置 zTree 是否处于编辑状态。注意，在正式环境下开启请慎重。
            enable: true,
            // 重命名文本是否全部选中。
            editNameSelectAll: true,
            // 显示删除按钮
            removeTitle: "删除",
            showRemoveBtn: showRemoveBtn,
            showRenameBtn: false
        },
        data: {
            key: {
                name: "name",
                title: "name"
            },
            simpleData: {
                enable: true,
                idKey: "id",
                pIdKey: "pid",
                rootPId: null
            }
        },
        callback: {
            beforeRemove: beforeRemove,
            beforeDrag: beforeDrag,
            beforeDrop: beforeDrop,
            beforeDragOpen: beforeDragOpen,
            onDrop: onDrop,
            onAsyncError: onAsyncError,
            onAsyncSuccess: onAsyncSuccess
        }
    };

    /**
     * 添加自定义的菜单操作。
     *
     * @param treeId
     *            树的id
     * @param treeNode
     *            触发事件的节点
     */
    function addHoverDom(treeId, treeNode) {
        var sObj = $("#" + treeNode.tId + "_span");
        if (treeNode.level != 0) {
            // 添加禁用按钮
            if (adminTreeSetting.callback.addDisableBtn) {
                adminTreeSetting.callback.addDisableBtn(treeId, treeNode);
            }
        }
        // 添加详情按钮
        if (treeNode.editNameFlag || $("#infoBtn_" + treeNode.tId).length > 0) {
            return;
        }
        var infoStr = "<span class='button info'  id='infoBtn_" + treeNode.tId + "' title='详情' onfocus='this.blur();'></span>";

        // 如果根菜单，则没有删除按钮。
        if (treeNode.level != 0) {
            var rObj = $("#" + treeNode.tId + "_remove");
            rObj.after(infoStr);
        } else {
            sObj.after(infoStr);
        }

        var infoBtn = $("#infoBtn_" + treeNode.tId);
        if (infoBtn) {
            infoBtn.bind("click", function () {
                adminTreeSetting.callback.nodeInfo(treeId, treeNode);
            });
        }

        // 功能节点不能再添加菜单或功能
        if (treeNode.type == "FUNCTION") {
            return;
        }
        // 添加增加子节点按钮
        if (treeNode.editNameFlag || $("#addNodeBtn_" + treeNode.tId).length > 0) {
            return;
        }

        var addNodeStr = "<span class='button add' id='addNodeBtn_" + treeNode.tId + "' title='添加" + tree.nodeName + "' onfocus='this.blur();'></span>";
        sObj.after(addNodeStr);
        var addNodeBtn = $("#addNodeBtn_" + treeNode.tId);
        if (addNodeBtn) {
            addNodeBtn.bind("click", function () {
                adminTreeSetting.callback.addNode(treeId, treeNode);
                return false;
            });
        }
        // 往叶子节点添加节点。比如菜单树的叶子菜单添加功能，机构树添加树添加人员。
        if (adminTreeSetting.callback.addLeaf) {
            adminTreeSetting.callback.addLeaf(treeId, treeNode);
        }
    }
    ;

    /**
     * 显示删除按钮
     *
     * @param treeId
     *            树的id
     * @param treeNode
     *            触发事件的节点
     * @returns true表示该节点不是根节点
     */
    function showRemoveBtn(treeId, treeNode) {
        return treeNode.level != 0;
    }

    /**
     * 隐藏自定义的菜单操作。
     *
     * @param treeId
     *            树的id
     * @param treeNode
     *            触发事件的节点
     */
    function removeHoverDom(treeId, treeNode) {
        if (adminTreeSetting.callback.removeHoverDom) {
            adminTreeSetting.callback.removeHoverDom(treeId, treeNode);
        }
        $("#addNodeBtn_" + treeNode.tId).unbind().remove();
        $("#infoBtn_" + treeNode.tId).unbind().remove();
    }
    ;

    function filter(treeId, parentNode, childNodes) {
        if (!childNodes)
            return null;
        for (var i = 0, l = childNodes.length; i < l; i++) {
            if (childNodes[i].name) {
                childNodes[i].name = childNodes[i].name.replace(/\.n/g, '.');
            }
        }
        return childNodes;
    }

    /**
     * 输入框获得焦点事件，给class加上empty值。
     *
     * @param e
     */
    function focusKey(e) {
        if (treeSearchKey.hasClass("empty")) {
            treeSearchKey.removeClass("empty");
        }
    }

    /**
     * 输入框失去焦点事件，去除class的empty值。
     *
     * @param e
     */
    function blurKey(e) {
        if (treeSearchKey.get(0).value === "") {
            treeSearchKey.addClass("empty");
        }
    }

    /**
     * 模糊查询节点。
     *
     * @param e
     *            事件
     */
    function searchNode(e) {
        var zTree = $.fn.zTree.getZTreeObj(tree.treeId);
        var value = $.trim(treeSearchKey.get(0).value);
        if (treeSearchKey.hasClass("empty")) {
            value = "";
        }
        if (value === "") {
            return;
        }
        updateNodes(false);
        nodeList = zTree.getNodesByParamFuzzy("name", value);
        updateNodes(true);
    }

    /**
     * 对查询的节点是否高亮显示，如果要高亮显示，还要展开这些节点。
     *
     * @param highlight
     *            是否高亮
     */
    function updateNodes(highlight) {
        var zTree = $.fn.zTree.getZTreeObj(tree.treeId);
        for (var i = 0, l = nodeList.length; i < l; i++) {
            nodeList[i].highlight = highlight;
            zTree.updateNode(nodeList[i]);
            if (highlight) {
                // 展开节点的父节点
                zTree.expandNode(nodeList[i].getParentNode(), true, false, false, false);
            }
        }
    }

    /**
     * 单击节点时，可以直接展开树
     *
     * @param treeId
     *            树id
     * @param treeNode
     *            节点
     * @returns true表示允许展开
     */
    function beforeClick(treeId, treeNode) {
        var zTree = $.fn.zTree.getZTreeObj(treeId);
        if (treeNode.isParent) {
            zTree.expandNode(treeNode);
            return false;
        }
    }
    ;

    /**
     * 找到节点的根节点。
     *
     * @param child
     * @returns
     */
    function findRootNode(child) {
        var pNode = child;
        while (pNode && pNode.level !== 0) {
            pNode = pNode.getParentNode();
        }
        return pNode;
    }

    /**
     * 导航菜单点击事件
     *
     * @param treeId
     * @param node
     * @returns
     */
    function navigateBeforeClick(treeId, node) {

        // 如果点击的不是上一次的节点，才改变背景色。
        if (node !== curMenu) {

            // 看他们的父节点是否是同一个，如果是，则不用收拢根菜单，否则需要收拢。
            var curPmenu = findRootNode(curMenu);
            var pMenu = findRootNode(node);
            if (pMenu !== curPmenu) {
                removeNodeClass(curPmenu);
                removeNodeClass(curMenu);
                zTree_Menu.expandNode(curPmenu, false);
            } else {
                removeNodeClass(curMenu);
            }
            addClass2Node(pMenu);
            addClass2Node(node);
            curMenu = node;
            zTree_Menu.expandNode(node, true);
        }

        var url = node.url;

        // 没有填写url的，则不用去获取menuId。
        if (url) {
            var menuId = getQueryString(url, "menuId");
            if (!menuId) {
                node.url = ChangeParam(url, "menuId", node.id);
                zTree_Menu.updateNode(node);
            }
            addTab(node.name, node.url, "", true);
        }

        return !node.isParent;
    }

    /**
     * 根据菜单的级别设置样式
     *
     * @param node
     */
    function addStyleByNodeLevel(node) {
        if (!node.htmlCode) {
            if (node.level == 0) {
                node.htmlCode = "<span style='" + navStyle + "'>" + node.name + "</span>";
            } else if (node.level == 1) {
                node.htmlCode = "<span style='" + nav1Style + "'>" + node.name + "</span>";
            } else if (node.level == 2) {
                node.htmlCode = "<span style='" + nav2Style + "'>" + node.name + "</span>";
            } else {
                node.htmlCode = "<span style='" + nav3Style + "'>" + node.name + "</span>";
            }
        }
        zTree_Menu.updateNode(node);
        var children = node.children;
        if (children) {
            $.each(children, function (i, child) {

                // 递归为该菜单下的所有菜单也加上style。
                addStyleByNodeLevel(child);
            });
        }
    }

    /**
     * 清除查询结果。
     */
    function clearSearchResult() {
        updateNodes(false);
    }

    function onDrop(event, treeId, treeNodes, targetNode, moveType, isCopy) {
        var zTree = $.fn.zTree.getZTreeObj(treeId);
        zTree.refresh();
        $(treeNodes).each(function (i) {
            zTree.expandNode(treeNodes[i], true, true, true, false);
        });
    }

    function beforeDrag(treeId, treeNodes) {
        for (var i = 0, l = treeNodes.length; i < l; i++) {
            if (treeNodes[i].drag === false) {
                curDragNodes = null;
                return false;
            } else if (treeNodes[i].parentTId && treeNodes[i].getParentNode().childDrag === false) {
                curDragNodes = null;
                return false;
            }
        }
        curDragNodes = treeNodes;
        return true;
    }

    function beforeDragOpen(treeId, treeNode) {
        autoExpandNode = treeNode;
        return true;
    }

    /**
     * 拖拽节点放开之前的事件，如果后台没有操作成功，则该事件不应该生效。
     *
     * @param treeId
     *            树id
     * @param treeNodes
     *            受影响的节点
     * @param targetNode
     *            目标节点
     * @param moveType
     *            移动类型
     * @returns true表示事件生效
     */
    function beforeDrop(treeId, treeNodes, targetNode, moveType) {
        // 不允许被拖拽为根节点
        var isRoot = (targetNode == null || (moveType != "inner" && !targetNode.parentTId));
        if (isRoot) {
            return false;
        }
        // 先在后台修改数据。
        $.ajax({
            url: treeUrl,
            data: "theMenuId=" + treeNodes[0].id + "&targetId=" + targetNode.id + "&moveType=" + moveType,
            dataType: "json",
            method:"post",
            async: false,
            success: function (result) {
                // 目前尚不能根据result的结果来操作树，原因是ajax不是同步的，但是已设置了async还是无效，原因尚不明！
                if (result.success) {
                    return true;
                } else {
                    Dialog.alert("操作失败!", "将重新加载树!", "error", function () {
                        var zTree = $.fn.zTree.getZTreeObj(treeId);
                        // 这里重新刷新目标节点会出问题，原因没有找到。只能重新刷新整个树
                        zTree.reAsyncChildNodes(null, "refresh");
                    });
                }
            }
        });
        // return true;
    }

    /**
     * 删除节点前的提示
     *
     * @param treeId
     *            树的id
     * @param treeNode
     *            触发事件的节点
     * @returns 弹出确认框
     */
    function beforeRemove(treeId, treeNode) {
        var zTree = $.fn.zTree.getZTreeObj(treeId);
        zTree.selectNode(treeNode);
        Dialog.confirm('确认', '确认删除' + treeNode.name + '?', function (r) {
            if (r) {
                $.ajax({
                    url: treeUrl.del,
                    data: {
                        id: treeNode.id
                    },
                    async: false,
                    type: "POST",
                    dataType: "json",
                    success: function (result) {
                        if (result.status == "success") {
                            zTree.removeNode(treeNode);
                            $.messager.show({
                                msg: '删除成功',
                                showType: 'show',
                                timeout: 1000,
                                style: {}
                            });
                        } else if (result.status == "fail") {
                            $.messager.alert("警告", "删除失败", "error");
                        } else {
                            $.messager.alert("警告", "删除失败，请联系系统管理员", "error");
                        }
                    },
                    timeout: function () {
                        $.messager.show({
                            msg: '删除 请求超时，请稍后再试',
                            showType: 'show',
                            timeout: 3000
                        });
                    },
                    error: function (XMLHttpRequest, textStatus) {
                        // 请求失败时应如何处理？暂未搞定。
                    }
                });
            }
        });
        return false;
    }

    /**
     * 否允许成为目标节点的子节点
     *
     * @param treeId
     *            树id
     * @param nodes
     *            被拖拽的节点 JSON 数据集合
     * @param targetNode
     *            拖拽时的目标节点 JSON 数据对象
     * @returns true表示允许
     */
    function dropInner(treeId, nodes, targetNode) {
        if (targetNode && targetNode.dropInner === false) {
            return false;
        } else {
            for (var i = 0, l = curDragNodes.length; i < l; i++) {
                if (!targetNode && curDragNodes[i].dropRoot === false) {
                    return false;
                } else if (curDragNodes[i].parentTId && curDragNodes[i].getParentNode() !== targetNode && curDragNodes[i].getParentNode().childOuter === false) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 否允许移动到目标节点后面
     *
     * @param treeId
     *            树id
     * @param nodes
     *            被拖拽的节点 JSON 数据集合
     * @param targetNode
     *            拖拽时的目标节点 JSON 数据对象
     * @returns true表示允许
     */
    function dropNext(treeId, nodes, targetNode) {
        var pNode = targetNode.getParentNode();
        if (pNode && pNode.dropInner === false) {
            return false;
        } else {
            for (var i = 0, l = curDragNodes.length; i < l; i++) {
                var curPNode = curDragNodes[i].getParentNode();
                if (curPNode && curPNode !== targetNode.getParentNode() && curPNode.childOuter === false) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 否允许移动到目标节点前面的操作。
     *
     * @param treeId
     *            树id
     * @param nodes
     *            被拖拽的节点 JSON 数据集合
     * @param targetNode
     *            拖拽时的目标节点 JSON 数据对象
     * @returns true标识允许拖拽
     */
    function dropPrev(treeId, nodes, targetNode) {
        var pNode = targetNode.getParentNode();
        if (pNode && pNode.dropInner === false) {
            return false;
        } else {
            for (var i = 0, l = curDragNodes.length; i < l; i++) {
                var curPNode = curDragNodes[i].getParentNode();
                if (curPNode && curPNode !== targetNode.getParentNode() && curPNode.childOuter === false) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 个性化文字样式
     *
     * @param treeId
     * @param treeNode
     */
    function getFontCss(treeId, treeNode) {
        var font = {
            color: "#333",
            "font-weight": "normal"
        };
        // 如果是查询，被查询出来的结果显示为红色，被禁用的节点依然显示为灰色。
        if (treeNode.highlight) {
            if (treeNode.enable == "N") {
                font = {
                    color: "#999"
                };
            } else {
                font = {
                    color: "#A60000",
                    "font-weight": "bold"
                };
            }
        } else {
            if (treeNode.enable == "N") {
                font = {
                    color: "#999"
                };
            }
        }
        if (treeNode.status == 2) {
            font = {
                color: "#999"
            };
        }
        return font;
    }

    /**
     * 获取管理性质的tree
     */
    var getTree4Admin = function (setting) {
        self.setting = $.extend(true, adminTreeSetting, setting);
        return init();
    };

    /**
     * 或去简单的tree
     */
    var getTree = function (setting) {
        self.setting = $.extend(true, readOnlySetting, setting);
        return init();
    };

    /**
     * 初始化
     */
    var init = function () {
        var $tree;
        if (setting.selector) {
            $tree = setting.selector;
        } else {
            $tree = $(setting.treeId);
        }
        $tree.removeClass("ztree").addClass("ztree");
        zTreeObj = $.fn.zTree.init($tree, self.setting);
        return zTreeObj;
    };

    /**
     * 获取已选择的id
     * @param treeId
     * @returns {Array}
     */
    var getSelectedIds = function (treeId) {
        var nodes = zTreeObj.getSelectedNodes();
        var selectedIds = [];
        $.each(nodes, function (i, node) {
            selectedIds.push(node.id);
        });
        return selectedIds;

    }

    return {
        getTree4Admin: getTree4Admin,
        getTree: getTree,
        getSelectedIds: getSelectedIds
    };
}();
